#ifndef TRAFFIC_JAM_CROSS_HPP
#define TRAFFIC_JAM_CROSS_HPP

#include "pthreadwrapper.hpp"
#include "direction.hpp"
#include "quadruple.hpp"
#include "cars.hpp"
#include "queue.hpp"
#include "car_logic.hpp"
#include <functional>
#include <bitset>

/* ========
 * 十字路口
 * ======== */

namespace jam {


/* 十字路口结构
 *   |
 *   |
 *   NE--
 * --WS
 *    |
 *    |
 */

template<direction_t dir>
using QueueCons = Queue<dir, car_logic<dir>>;

typedef quadruple<quad_type_cons<QueueCons>::cons> queue_quadruple_t;

/* 我们需要一个用不完整类型构造的实例 */
class Crossroad;
extern Crossroad crossroad;
#define QUEUE_FIELD(dir) QUAD_FIELD(queue_quadruple_t, crossroad.queue_quadruple, dir)


class Crossroad {
 public:
  void add_cars(Directions &);
  void schedule();
 private:
  typedef std::bitset<4> counter_t;
  mutex::mutex_quad_t mutex_quad;
  queue_quadruple_t::type queue_quadruple;
  void inline dead_lock_scheduler();
  void inline right_first_scheduler();
  void inline happy_end_scheduler();
  /* 用于循环展开的模板 */
  template <direction_t dir>
  struct _tpl {
    static void function() {
      QUEUE_FIELD(dir).emit();
    }
  };
};


}


#endif //TRAFFIC_JAM_CROSS_HPP
